/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
// 使用FreeRTOS 
#define MODBUS_SLAVE_USE_FREERTOS 1

#if MODBUS_SLAVE_USE_FREERTOS
#include "FreeRTOS.h"     // FreeRTOS 核心头文件（内核功能）
#include "task.h"
#include "event_groups.h" // FreeRTOS 事件组头文件（事件同步核心）

#ifndef portVECTACTIVE_MASK
// 定义 VECTACTIVE 字段掩码（低9位，覆盖所有可能的中断号）
#define portVECTACTIVE_MASK  (0xFFUL)
#endif

/* ----------------------- Variables ----------------------------------------*/
// 从机事件句柄
static EventGroupHandle_t xEventGroupSlaveHdl;

#define MB_SLAVE_EVENT_POLL_MASK      (EventBits_t)(EV_READY |          \
											EV_FRAME_RECEIVED | \
											EV_EXECUTE |        \
											EV_FRAME_SENT)

/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBPortEventInit(void)
{
    xEventGroupSlaveHdl = xEventGroupCreate();
    return xEventGroupSlaveHdl == NULL ? FALSE : TRUE;
}

BOOL
xMBPortEventPost(eMBEventType eEvent)
{
    BOOL bStatus = FALSE;                   // 事件发送结果：默认失败
    // 检查中断控制状态寄存器 判断是否在中断中
        //读取 ARM Cortex-M 内核的硬件寄存器状态 来判断当前是否处于中断上下文
      //portNVIC_INT_CTRL_REG 是 ARM Cortex-M 内核中 NVIC（嵌套向量中断控制器)
      //portVECTACTIVE_MASK（提取有效字段）portVECTACTIVE_MASK 的值固定为 0xFFUL（二进制 11111111），其作用是 精确提取 VECTACTIVE 字段
    if ((portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK) != 0) {
        // 高优先级任务唤醒标志：默认未唤醒
        BaseType_t xHigherPriorityTaskWoken = pdFALSE;
        BaseType_t xResult = xEventGroupSetBitsFromISR(xEventGroupSlaveHdl,
            (EventBits_t)eEvent, &xHigherPriorityTaskWoken);
        // 检查事件设置结果
        if (xResult == pdPASS) {
            // 事件设置成功：若唤醒了高优先级任务，触发上下文切换
            portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
            bStatus = TRUE; // 标记发送成功
        } else {
            bStatus = FALSE; // 标记发送失败（如事件组资源不足）
        }
    } else {
        // 在任务中
        (void)xEventGroupSetBits(xEventGroupSlaveHdl, (EventBits_t)eEvent);
        bStatus = TRUE;
    }
    return bStatus;
}

BOOL
xMBPortEventGet(eMBEventType* eEvent)
{
    EventBits_t uxBits; // 存储从事件组中获取的事件位
    BOOL xEventHappened = FALSE; // 事件接收结果：默认未接收到

    // 等待事件组中的“轮询事件”
    uxBits = xEventGroupWaitBits(xEventGroupSlaveHdl, //事件组句柄
        MB_SLAVE_EVENT_POLL_MASK,   // 等待的事件掩码（仅关注轮询相关事件）
        pdTRUE,         // 获取事件后自动清除对应的事件位（避免重复处理）
        pdFALSE,        // 无需等待所有事件位，只要有一个事件位被设置就返回
        portMAX_DELAY); // 永久等待（直到有事件触发)

    // 检查是否接收到有效轮询事件
    if (uxBits & MB_SLAVE_EVENT_POLL_MASK) {
        *eEvent = (eMBEventType)(uxBits & MB_SLAVE_EVENT_POLL_MASK); // 存储有效事件
        xEventHappened = TRUE; // 标记接收到事件
    } else {
        *eEvent = (eMBEventType)uxBits; // 存储无效事件（用于调试）
        xEventHappened = FALSE; // 标记未接收到事件
    }
    return xEventHappened;
}
#else
/* ----------------------- Variables ----------------------------------------*/
static eMBEventType eQueuedEvent;
static BOOL     xEventInQueue;

/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBPortEventInit(void)
{
    xEventInQueue = FALSE;
    return TRUE;
}

BOOL
xMBPortEventPost(eMBEventType eEvent)
{
    xEventInQueue = TRUE;
    eQueuedEvent = eEvent;
    return TRUE;
}

BOOL
xMBPortEventGet(eMBEventType* eEvent)
{
    BOOL            xEventHappened = FALSE;

    if (xEventInQueue) {
        *eEvent = eQueuedEvent;
        xEventInQueue = FALSE;
        xEventHappened = TRUE;
    }
    return xEventHappened;
}
#endif







